package cn.tsyz.local.modules.auth.interceptor;

import cn.tsyz.local.modules.user.model.User;
import cn.tsyz.local.modules.user.service.UserService;
import cn.tsyz.local.shared.security.JwtUtil;
import cn.tsyz.local.util.CookieUtil;
import cn.tsyz.local.util.UserContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
@Component
public class AuthInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private UserService userService;

    @Autowired
    private CookieUtil cookieUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        String requestURI = request.getRequestURI();
        String method = request.getMethod();

        log.debug("AuthInterceptor拦截请求: {} {} ", method, requestURI);

        // 排除不需要登录验证的路径
        if (shouldExcludeFromAuth(requestURI)) {
            log.debug("路径 {} 被排除在认证之外", requestURI);
            return true;
        }

        // 检查是否是API请求
        boolean isApiRequest = requestURI.startsWith("/api/");

        // 从Cookie中获取Token
        String token = cookieUtil.getTokenFromCookie(request);
        log.debug("从Cookie中获取到Token: {}", token != null ? "存在" : "不存在");

        // 验证Token
        if (token != null && jwtUtil.validateToken(token)) {
            // 从Token获取用户信息
            Long userId = jwtUtil.getUserIdFromToken(token);
            String username = jwtUtil.getUsernameFromToken(token);

            log.debug("Token验证通过，用户ID: {}, 用户名: {}", userId, username);

            // 查询用户信息
            User user = userService.findById(userId);

            if (user != null && user.getEnabled() && user.getUsername().equals(username)) {
                // 将用户信息存储到ThreadLocal中
                UserContextHolder.setUser(user);
                log.debug("用户认证成功: {}", username);
                return true;
            } else {
                log.warn("用户验证失败: 用户不存在或被禁用, userId={}, username={}", userId, username);
            }
        }

        // Token无效或用户不存在
        if (isApiRequest) {
            // API请求返回JSON错误响应
            log.info("API请求未认证，返回401错误: {} {}", method, requestURI);
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write("{\"success\":false,\"message\":\"未授权访问，请先登录\"}");
            return false;
        } else {
            // 页面请求重定向到登录页面
            log.info("页面请求未认证，重定向到登录页面: {} {}", method, requestURI);
            response.sendRedirect("/login");
            return false;
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
                                Object handler, Exception ex) throws Exception {
        // 请求完成后清除ThreadLocal中的用户信息
        UserContextHolder.clear();
        log.debug("清除ThreadLocal中的用户上下文");
    }

    /**
     * 判断是否应该排除在认证之外
     */
    private boolean shouldExcludeFromAuth(String requestURI) {
        return requestURI.startsWith("/login") ||
                requestURI.startsWith("/api/login") ||
                requestURI.startsWith("/api/logout") ||
                requestURI.startsWith("/static/") ||
                requestURI.equals("/") ||  // 根路径排除
                requestURI.equals("/favicon.ico") ||
                requestURI.endsWith(".css") ||
                requestURI.endsWith(".js") ||
                requestURI.endsWith(".png") ||
                requestURI.endsWith(".jpg") ||
                requestURI.endsWith(".jpeg") ||
                requestURI.endsWith(".gif") ||
                requestURI.endsWith(".html");
    }
}
